1

介绍

Handlebars 让你能够有能力高效地容易地创立语义化的模版。Handlebars兼容Mustache语法,在大多数情况下它可以读取Mustache的语法并在你当前模板中使用。具体点击这里

安装

  1. 下载
  2. npm install --save handlebars
  3. bower install --save handlebars

具体参考

开始使用

Handlebars 模板看起来就像嵌套handlebars表达式的规范的HTML。

<div class="entry">
  <h1>{{title}}</h1>
  <div class="body">
    {{body}}
  </div>
</div>

handlebars表达式: {{ cnt }}
你也可以通过<script>标签包裹handlebars表达式传递模板给浏览器:

<script id="entry-template" type="text/x-handlebars-template">
  <div class="entry">
    <h1>{{title}}</h1>
    <div class="body">
      {{body}}
    </div>
  </div>
</script>
你必须把模板放在<script>标签里,这很重要。不要直接把它放在HTML中否则HTML的解析会改变模板内容。

JavaScript中,使用Handlebars.compile来编译模板:

var source   = $("#entry-template").html();
var template = Handlebars.compile(source);
// ‘entry-template’就是包裹模板的script的id
注意这种方法在产品应用中不推荐使用。更好的方法是预编译你的模版。这将使要求的运行库更小,模板不必在浏览器中编译,显著地节省了时间。这在移动设备上尤为重要。

在JavaScript中,使用Handlebars.compile()方法来预编译模板 例如:(这是一套规则)

//用jquery获取模板
var tpl   =  $("#tpl").html();
//原生方法
var source = document.getElementById('#tpl').innerHTML;
//预编译模板
var template = Handlebars.compile(source);
//模拟json数据
var context = { name: "zhaoshuai", content: "learn Handlebars"};
//匹配json内容
var html = template(context);
//输入模板
$(body).html(html);

通过解析context处理handlebars模板获取HTML内容

var context = {title: "My New Post", body: "This is my first post!"};
var html    = template(context);

输出html:

<div class="entry">
  <h1>My New Post</h1>
  <div class="body">
    This is my first post!
  </div>
</div>

HTML转码

Handlebars 的转码HTML值通过{{expression}}返回. 如果你不想handlebars转码一个值的话,使用{{{expression}}}

<div class="entry">
  <h1>{{title}}</h1>
  <div class="body">
    {{{body}}}
  </div>
</div>

上下文内容:

{
  title: "All about <p> Tags",
  body: "<p>This is a post about &lt;p&gt; tags</p>"
}

输出:

<div class="entry">
  <h1>All About &lt;p&gt; Tags</h1>
  <div class="body">
    <p>This is a post about &lt;p&gt; tags</p>
  </div>
</div>

Handlebars 不会转义 Handlebars.SafeString. 如果你写了输出本身所含HTML的辅助 helper, 你其实想返回一个新的Handlebars.SafeString.在这种情况下,你想手动拼接参数.

Handlebars.registerHelper('link', function(text, url) {
  text = Handlebars.Utils.escapeExpression(text);
  url  = Handlebars.Utils.escapeExpression(url); 
  var result = '<a href="' + url + '">' + text + '</a>';    
  return new Handlebars.SafeString(result);
});

这样可以避免字符串被转码,正确响应参数,即使你不适用{{{也不会被转码。

块级表达式

块级表达式 允许你定义一个可以触发一个与当前不同的上下文来替换模板的相应内容的helper。这些块级辅助helper通过在helper的名字前加#并在结束时名字前加/:

{{#list people}}{{firstName}} {{lastName}}{{/list}}

渲染context:

{
  people: [
    {firstName: "Yehuda", lastName: "Katz"},
    {firstName: "Carl", lastName: "Lerche"},
    {firstName: "Alan", lastName: "Johnson"}
  ]
}

我们会创建一个叫list的helper输出HTML列表。该列表以people为第一个参数,哈希选项为第二个参数。这些选项里包含一条名为fn的属性,在handlebars模板中通过这些属性名获取值

Handlebars.registerHelper('list', function(items, options) {
  var out = "<ul>";

  for(var i=0, l=items.length; i<l; i++) {
    out = out + "<li>" + options.fn(items[i]) + "</li>";
  }

  return out + "</ul>";
});

渲染结果:

<ul>
  <li>Yehuda Katz</li>
  <li>Carl Lerche</li>
  <li>Alan Johnson</li>
</ul>

块级辅助helper有很多特点,例如可以创建一个else部分.因为当你调用options.fn(context)时块级helper的内容已经被转码过,所以handlebars不会再去转码helper的内容。

handler 的路径

Handlebars 支持简单的路径,就像 Mustache.

<p>{{name}}</p>

Handlebars 也支持嵌套的属性,比如对象的属性.

<div class="entry">
  <h1>{{title}}</h1>
  <h2>By {{author.name}}</h2>

  <div class="body">
    {{body}}
  </div>
</div>

模板工作的对象context:

var context = {
  title: "My First Blog Post!",
  author: {
    id: 47,
    name: "Yehuda Katz"
  },
  body: "My first post. Wheeeee!"
};

这使得使用handlebars模板处理JSON字符串成为可能。内嵌的handlebars的路径也包括../语法,相当于当前路径的父级。

<h1>Comments</h1>

<div id="comments">
  {{#each comments}}
  <h2><a href="/posts/{{../permalink}}#{{id}}">{{title}}</a></h2>
  <div>{{body}}</div>
  {{/each}}
</div>

{{permalink}}
{{#each comments}}
  {{../permalink}}

  {{#if title}}
    {{../permalink}}
  {{/if}}
{{/each}}

这里例子中引用了相同的permalink即使他们在不同的块中。这种行为是新的,handlebars4支持。

Handlebars的内置块表达式(Block helper)

  1. each block helper
    你可以使用内置的{{#each}} helper遍历列表块内容,用this来引用遍历的元素 例如:

       <ul>  
           {{#each name}}
               <li>{{this}}</li>
           {{/each}}
       </ul>  

    对应适用的json数据

       {
           name: ["html","css","javascript"]
       };

    这里的this指的是数组里的每一项元素,和上面的Block很像,但原理是不一样的这里的name是数组,而内置的each就是为了遍历数组用的,更复杂的数据也同样适用。

  2. if else block helper
    {{#if}}就你使用JavaScript一样,你可以指定条件渲染DOM,如果它的参数返回false,undefined, null, "" 或者 [] (a "falsy" value), Handlebar将不会渲染DOM,如果存在{{#else}}则执行{{#else}}后面的渲染。

       {{#if list}}
       <ul id="list">  
           {{#each list}}
               <li>{{this}}</li>
           {{/each}}
       </ul>  
       {{else}}
           <p>{{error}}</p>
       {{/if}}

    对应适用json数据

    var data = {info:['HTML5','CSS3',"WebGL"],"error":"数据取出错误"}

    这里{{#if}}判断是否存在list数组,如果存在则遍历list,如果不存在输出错误信息

  3. unless block helper
    {{#unless}}这个语法是反向的if语法也就是当判断的值为false时他会渲染DOM 例如:

       {{#unless data}}
       <ul id="list">  
           {{#each list}}
               <li>{{this}}</li>
           {{/each}}
       </ul>  
       {{else}}
           <p>{{error}}</p>
       {{/unless}}
  4. with block helper
    {{#with}}一般情况下,Handlebars模板会在编译的阶段的时候进行context传递和赋值。使用with的方法,我们可以将context转移到数据的一个section里面(如果你的数据包含section)。 这个方法在操作复杂的template时候非常有用。

       <div class="entry">  
         <h1>{{title}}</h1>
         {{#with author}}
         <h2>By {{firstName}} {{lastName}}</h2>
         {{/with}}
       </div>  

    对应适用json数据

       {
         title: "My first post!",
         author: {
           firstName: "Charles",
           lastName: "Jolley"
         }
       }
    

Handlebar的注释(comments)

Handlebars也可以使用注释写法如下

{{! handlebars comments }}

Handlebars的访问(Path)

Handlebar支持路径和mustache,Handlebar还支持嵌套的路径,使得能够查找嵌套低于当前上下文的属性
可以通过.来访问属性也可以使用../,来访问父级属性。 例如:(使用.访问的例子)

<h1>{{author.id}}</h1>  

对应json数据

{
  title: "My First Blog Post!",
  author: {
    id: 47,
    name: "Yehuda Katz"
  },
  body: "My first post. Wheeeee!"
  };

例如:(使用../访问)

{{#with person}}
    <h1>{{../company.name}}</h1>
{{/with}}

对应适用json数据

{
    "person":
    { "name": "Alan" },
        company:
    {"name": "Rad, Inc." }
};

自定义helper

Handlebars,可以从任何上下文可以访问在一个模板,你可以使用Handlebars.registerHelper()方法来注册一个helper。

调试技巧

把下面一段"debug helper"加载到你的JavaScript代码里,然后在模板文件里通过{{debug}}或是{{debug someValue}}方便调试数据

Handlebars.registerHelper("debug", function(optionalValue) {  
  console.log("Current Context");
  console.log("====================");
  console.log(this);
  if (optionalValue) {
    console.log("Value");
    console.log("====================");
    console.log(optionalValue);
  }
});

handlebars的jquery插件

(function($) {
    var compiled = {};
    $.fn.handlebars = function(template, data) {
        if (template instanceof jQuery) {
            template = $(template).html();
        }
    compiled[template] = Handlebars.compile(template);
    this.html(compiled[template](data));
    };
})(jQuery);
$('#content').handlebars($('#template'), { name: "Alan" });

Mr_zhang
395 声望10 粉丝

步步向“前”